﻿/*
 * Сделано в SharpDevelop.
 * Пользователь: Кулик
 * Дата: 29.03.2011
 * Время: 15:43
 * 
 * Для изменения этого шаблона используйте Сервис | Настройка | Кодирование | Правка стандартных заголовков.
 */
using System;
using System.Collections.Generic;
using System.IO;
using NLog;

namespace Video
{
	/// <summary>
	/// Description of MyClass.
	/// </summary>
	public class VideoStream: IDisposable
	{
		public BinaryWriter outVideoStream;
		public BinaryReader inVideoStream;
		
		public VideoStream(string filePath, bool thisIsFileOut = false){
			if(thisIsFileOut){
				outVideoStream = new BinaryWriter(File.Create(filePath));
			}
			else{
				inVideoStream = new BinaryReader(File.OpenRead(filePath));
			}
		}
		#region Write to Stream
		public void Flush(){
			outVideoStream.Flush();
		}
		
		public void avio_w8(byte data){
			outVideoStream.Write(data);
		}
		
		public void avio_wl32(uint val){
			outVideoStream.Write(val);
		}
		
		public void avio_wb32(uint val)
		{
			uint temp = (val >> 24) & (255);
			avio_w8((byte)(temp));
			temp = (val >> 16) & (255);
			avio_w8((byte)(temp));			
			temp = (val >> 8) & (255);
			avio_w8((byte)(temp));			
			temp = (val) & (255);
			avio_w8((byte)(temp));
		}
		
		public void avio_wl64(UInt64 val)
		{
			avio_wl32((uint)(val & 0xffffffff));
			avio_wl32((uint)(val >> 32));
		}

		public void avio_wb64(UInt64 val)
		{
			avio_wb32((uint)(val >> 32));
			avio_wb32((uint)(val & 0xffffffff));
		}

		public void avio_wl16(ushort val)
		{
			avio_w8((byte)val);
			avio_w8((byte)(val >> 8));
		}

		public void avio_wb16(ushort val)
		{
			ushort temp = (ushort)((val >> 8) & (255));
			avio_w8((byte)(temp));
			
			temp = (ushort)((val) & (255));
			avio_w8((byte)temp);
		}

		public void avio_wl24(uint val)
		{
			avio_wl16((ushort)(val & 0xffff));
			avio_w8((byte)(val >> 16));
		}

		public void avio_wb24(uint val)
		{
			avio_wb16((ushort)(val >> 8));
			avio_w8((byte)val);
		}
		
		#endregion
		
		#region Read from Stream
		public byte avio_r8()
		{
			byte result = 0;
			//if(inVideoStream.PeekChar()!=-1){
			result = inVideoStream.ReadByte();
			//	}
			return result;
		}
		
		public ushort avio_rl16()
		{
			ushort val;
			val = (ushort)avio_r8();
			val |= (ushort)(avio_r8() << 8);
			return val;
		}

		public uint avio_rl24()
		{
			uint val;
			val = avio_rl16();
			val |= (uint)(avio_r8()) << 16;
			return val;
		}

		public uint avio_rl32()
		{
			uint val;
			val = avio_rl16();
			val |= (uint)(avio_rl16()) << 16;
			return val;
		}

		public UInt64 avio_rl64()
		{
			UInt64 val;
			val = (UInt64)avio_rl32();
			val |= (UInt64)(avio_rl32() << 32);
			return val;
		}

		public ushort avio_rb16()
		{
			ushort val;
			val = (ushort)(avio_r8() << 8);
			val |= (ushort)avio_r8();
			return val;
		}

		public uint avio_rb24()
		{
			uint val;
			val = (uint)(avio_rb16()) << 8;
			val |= avio_r8();
			return val;
			
		}
		
		public uint avio_rb32()
		{
			uint val;
			val = (uint)(avio_rb16()) << 16;
			val |= (uint)avio_rb16();
			return val;
		}
		
		public ulong avio_rb64()
		{
			ulong val;
			val = (ulong)(avio_rb32()) << 32;
			val |= (ulong)avio_rb32();
			return val;
		}
		
		public string readPascalString(){
			byte b=0;
			char terminateChar = Convert.ToChar(b);
			char[] temp = new char[200];
			int index=-1;
			do {
				index++;
				temp[index] = Convert.ToChar(inVideoStream.ReadByte());
			}while(temp[index]!=terminateChar);
			
			return new String(temp,0,index);
		}
		#endregion
		
		public long avio_tell(){
			return inVideoStream.BaseStream.Position;
		}
		
		public long avio_seek( int offset, SeekOrigin whence)
		{
			return inVideoStream.BaseStream.Seek(offset, whence);
		}
		
		public void ffio_wfourcc(string s)
		{
			outVideoStream.Write(s);
		}
		
		
		public void Dispose()
		{
			if(outVideoStream != null){
				outVideoStream.Close();
			}
			
			if(inVideoStream != null){
				inVideoStream.Close();
			}
		}
	}
}